package com.ngmaster.socket;

import com.ngmaster.socket.connection.NetConnection;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TcpServer {

	private static Logger logger = LoggerFactory.getLogger(TcpServer.class);

	/**
	 * 线程函数
	 */
	protected Thread _thread = null;
	
	/**
	 * 初始化
	 * @param port
	 */
	public void init(final int port) {
		_thread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					start(port);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		_thread.start();
	}
	
	/**
	 * 启动
	 * @param port
	 * @throws Exception
	 */
    protected void start(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
        	ServerBootstrap b = new ServerBootstrap();  
            b.group(bossGroup, workerGroup)  
                    .channel(NioServerSocketChannel.class)  
                    .childHandler(new TcpChannel(new ITcpLogic() {
						
                    	@Override
						public void Inactive(ChannelHandlerContext ctx) {
							inactiveConnected(ctx);
						}
						
						@Override
						public void Active(ChannelHandlerContext ctx) {
							activeConnected(ctx);
						}

						@Override
						public void Receive(ChannelHandlerContext ctx, ByteBuf data) {
							receiveData(ctx, data);
						}
					})); 

            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    
    /**
     * 激活一个连接
     * @param ctx
     */
    protected void activeConnected(ChannelHandlerContext ctx) {
    	NetManager.getInstance().addConnection(ctx);
		logger.info("active connection:" + NetManager.getInstance().getConnectionByCtx(ctx).getClientIp());
	}
    
    /**
     * 失效一个连接
     * @param ctx
     */
    protected void inactiveConnected(ChannelHandlerContext ctx) {
		NetConnection netConnection = NetManager.getInstance().getConnectionByCtx(ctx);
		if (netConnection != null) {
			NetManager.getInstance().removeNetConnection(netConnection.getConnectionId());
			logger.info("inactive connection:" + netConnection.getClientIp());
		}
	}
    
    /**
     * 接收到数据
     */
    protected void receiveData(ChannelHandlerContext ctx, ByteBuf data) {
    	logger.info("receiveData:" + ctx + ", data:" + data);
    	if (ctx == null || data == null) {
			return;
		}
		NetConnection netConnection = NetManager.getInstance().getConnectionByCtx(ctx);
    	if (netConnection != null) {
			logger.info("receive data:" + netConnection.getClientIp());
		}
		NetManager.getInstance().receive(ctx, data);
	}
}
